package cn.bluech.lib.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

import androidx.annotation.RequiresApi;
import androidx.annotation.RequiresPermission;

import java.util.HashMap;
import java.util.Map;

/**
 * 关于获取IMEI/MEID的问题：
 * 在原本 4.0 系统上就一直存在一个 api, 但这个 api 在全网通和双卡上就比较佛系了...
 * 4.0： 也有双卡全网通的手机
 *     只能用 getDeviceId(), 基本策略就是：
 *        都不插卡的时候返回卡1的 IMEI
 *        卡1插什么卡返回什么号
 *        卡1不插卡时, 卡2插什么卡返回什么号
 * 5.0：
 *    Framework 提供了两个属性值 ril.cdma.meid 和 ril.gsm.imei, 需要用反射获取
 * 6.0：
 *    有系统 API 支持： getDeviceId(int slotId)
 *    但全网通手机初始化时只创建 GSMPhone 没有创建 CDMAPhone, 此时无法获取 MEID,
 *    只有当插入一张 CDMA(电信) 卡之后才会创建 CDMAPhone 替换其中的一个 GSMPhone,
 *    从而才能获取到 MEID, 但不能直接确定替换的是哪张卡，需要通过判断号码的长度
 * 需要权限： android.permission.READ_PHONE_STATE
 *
 * 关于获取蓝牙/wifi 的 MAC 问题：
 *     6.0 之后就禁用了(返回02:00:00:00:00:00)
 *     7.0 之后 /sys/class/net/wlan0/address 也取不到了
 *     总之，MAC 比较难获取了，有的需要开启 wifi 后才能获取正常的 mac
 */
public class DeviceUtils {
    public static final String KEY_ID_IMEI1 = "imei1";
    public static final String KEY_ID_IMEI2 = "imei2";
    public static final String KEY_ID_MEID = "meid";


    // 获取序列号
    public static String getSn(Context ctx) {
        try {
            return ReflectUtils.call("android.os.SystemProperties", "get", "ro.serialno");
        } catch (Throwable t) {
            t.printStackTrace();
            return null;
        }
    }

    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
    public static Map<String, String> getDeviceIdsFrom4(Context ctx) {
        Map<String, String> map = new HashMap<>();
        TelephonyManager manager = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
        if (null == manager)
            return map;
        String id = manager.getDeviceId();
        map.put(id.length()==15 ? KEY_ID_IMEI1 : KEY_ID_MEID, id);

        return map;
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) // Android 5.0
    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
    public static Map<String, String> getDeviceIdsFrom5(Context ctx) {
        Map<String, String> map = new HashMap<>();
        try {
            String imeis = ReflectUtils.call("android.os.SystemProperties", "get", "ril.gsm.imei");
            String meid = ReflectUtils.call("android.os.SystemProperties", "get", "ril.cdma.meid");
//            String gsm = (String) method.invoke(null, "ril.gsm.imei", "");
            map.put(KEY_ID_MEID, meid);

            if (!TextUtils.isEmpty(imeis)) {
                String[] imeiArray = imeis.split(",");
                map.put(KEY_ID_IMEI1, imeiArray[0]);
                if (imeiArray.length > 1)
                    map.put(KEY_ID_IMEI2, imeiArray[1]);
            }
        } catch (Throwable t) {
            t.printStackTrace();
        }

        return map;
    }

    /**
     * 在 Android 7.1 上似乎只能取到 IMEI
     */
    @RequiresApi(api = Build.VERSION_CODES.M) // Android 6.0
    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
    public static Map<String, String> getDeviceIdsFrom6(Context ctx) {
        Map<String, String> map = new HashMap<>();
        TelephonyManager manager = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
        if (null == manager)
            return map;

        String id1 = manager.getDeviceId(0);
        if (!TextUtils.isEmpty(id1))
            map.put(id1.length()==15 ? KEY_ID_IMEI1 : KEY_ID_MEID, id1);
        String id2 = manager.getDeviceId(1);
        if ((!TextUtils.isEmpty(id2))&&(!id2.equals(id1)))
            map.put(id2.length()==15 ? KEY_ID_IMEI2 : KEY_ID_MEID, id2);

        return map;
    }

    @RequiresApi(api = Build.VERSION_CODES.O) // Android 8.0
    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
    public static Map<String, String> getDeviceIdsFrom8(Context ctx) {
        Map<String, String> map = new HashMap<>();
        TelephonyManager manager = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
        if (null != manager) {
            map.put(KEY_ID_IMEI1, manager.getImei(0));
            map.put(KEY_ID_IMEI2, manager.getImei(1));
            map.put(KEY_ID_MEID, manager.getMeid()); // 好像还有meid1 meid2...
        }

        return map;
    }

    //    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
    @SuppressLint("MissingPermission")
    public static Map<String, String> getDeviceIds(Context ctx) {
        try {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
                return getDeviceIdsFrom4(ctx);
            else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
                return getDeviceIdsFrom5(ctx);
            else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
                return getDeviceIdsFrom6(ctx);
            else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q)
                return getDeviceIdsFrom8(ctx);
            else {
                try {
                    return getDeviceIdsFrom8(ctx);
                }catch (Exception e){
                    return new HashMap<>();
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            return new HashMap<>();
        }
    }

    public static String getDeviceId(Context ctx){
        Map<String, String> map = getDeviceIds(ctx);
        String imei1 = map.get(KEY_ID_IMEI1);
        String imei2 = map.get(KEY_ID_IMEI2);
        String meid = map.get(KEY_ID_MEID);

        if(TextUtils.isEmpty(imei1)){
            return TextUtils.isEmpty(imei2)?meid:imei2;
        }else
            return imei1;
    }
}

